package com.softserveinc.parser;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

import com.softserveinc.model.Certification;
import com.softserveinc.model.Movie;
import com.softserveinc.model.MovieDetails;

public class JsonParser implements Parser {

	private static final String TAG = JsonParser.class.getSimpleName();

	private static final String MOVIE_CERTIFICATION = "certification";
	private static final String IMAGE_SIZE_VALUE = "thumb";
	private static final String IMAGE_URL = "url";
	private static final String IMAGE_SIZE = "size";
	private static final String IMAGE = "image";
	private static final String POSTERS = "posters";
	private static final String MOVIE_RELEASED_DATE = "released";
	private static final String MOVIE_DATE_FORMAT = "yyyy-MM-dd";
	private static final String MOVIE_RATING = "rating";
	private static final String MOVIE_NAME = "name";
	private static final String MOVIE_ID = "id";
	private static final String JOB = "job";
	private static final String TRAILER_URL = "trailer";
	private static final String OVERVIEW = "overview";
	private static final String THUMB = "thumb";
	private static final String POSTER = "poster";
	private static final String BACKDROPS = "backdrops";
	private static final String ACTOR = "Actor";
	private static final int ACTORS_NEEDED_TO_DISPLAY = 4;

	public JsonParser() {
	}

	@Override
	public List<Movie> parseMovieList(final InputStream feedbackStream)
			throws JSONException {

		String responseText = getResponseText(feedbackStream);
		JSONArray jsonArray = new JSONArray(responseText);

		final List<Movie> movies = new ArrayList<Movie>();

		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject jsonObject = jsonArray.getJSONObject(i);

			Movie movie = new Movie();

			movie.setId(jsonObject.getInt(MOVIE_ID));
			movie.setTitle(jsonObject.getString(MOVIE_NAME));
			movie.setPopularity(jsonObject.getDouble(MOVIE_RATING));

			SimpleDateFormat fmt = new SimpleDateFormat(MOVIE_DATE_FORMAT);

			String dateValue = jsonObject.getString(MOVIE_RELEASED_DATE);

			try {
				movie.setReleaseDate(fmt.parse(dateValue));
			} catch (ParseException e) {
				movie.setReleaseDate(null);
			}

			JSONArray postersArray = jsonObject.getJSONArray(POSTERS);
			for (int j = 0; j < postersArray.length(); j++) {
				JSONObject poster = postersArray.getJSONObject(j)
						.getJSONObject(IMAGE);

				if (IMAGE_SIZE_VALUE.equalsIgnoreCase(poster
						.getString(IMAGE_SIZE))) {
					movie.setPosterHttpUrl(poster.getString(IMAGE_URL));

					Log.i(TAG, movie.getPosterHttpUrl());

					break;
				}
			}

			movie.setCertification(Certification
					.getCertificationForName(jsonObject
							.getString(MOVIE_CERTIFICATION)));

			movies.add(movie);
		}

		return movies;
	}

	@Override
	public MovieDetails parseMovieDetails(final InputStream feedbackStream)
			throws JSONException, ParseException {

		String responseText = getResponseText(feedbackStream);
		JSONArray jsonArray = new JSONArray(responseText);

		final MovieDetails movieDetails = new MovieDetails();

		JSONObject jsonObject = jsonArray.getJSONObject(0);

		movieDetails.setOverview(jsonObject.getString(OVERVIEW));
		movieDetails.setTrailerUrl(jsonObject.getString(TRAILER_URL));

		JSONArray actors = jsonObject.getJSONArray("cast");
		StringBuilder castBuilder = new StringBuilder();

		int castSize = 0;
		int castSizeNeeded = ACTORS_NEEDED_TO_DISPLAY;
		if (actors.length() < ACTORS_NEEDED_TO_DISPLAY) {
			castSizeNeeded = actors.length();
		}

		for (int i = 0; i < actors.length(); i++) {
			JSONObject actor = actors.getJSONObject(i);

			if (actor.getString(JOB).equalsIgnoreCase(ACTOR)) {
				castBuilder.append(actor.getString(MOVIE_NAME));
				castSize++;
				if (castSize == castSizeNeeded) {
					break;
				} else {
					castBuilder.append(", ");
				}
			}
		}

		movieDetails.setCast(castBuilder.toString());

		JSONArray backdrops = jsonObject.getJSONArray(BACKDROPS);

		List<String> thumbs = new ArrayList<String>();
		List<String> posters = new ArrayList<String>();
		for (int i = 0; i < backdrops.length(); i++) {
			JSONObject image = backdrops.getJSONObject(i).getJSONObject(IMAGE);

			if (image.getString(IMAGE_SIZE).equalsIgnoreCase(THUMB)) {

				thumbs.add(image.getString(IMAGE_URL));
			} else if (image.getString(IMAGE_SIZE).equalsIgnoreCase(POSTER)) {

				posters.add(image.getString(IMAGE_URL));
			}
		}

		movieDetails.setThumbHttpUrls(thumbs);
		movieDetails.setThumbHttpUrlsBig(posters);

		return movieDetails;
	}

	private String getResponseText(final InputStream feedbackStream) {
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				feedbackStream));
		StringBuilder builder = new StringBuilder();

		String line = null;
		try {
			while ((line = reader.readLine()) != null) {
				builder.append(line);
			}
		} catch (IOException e) {
			Log.e(TAG, e.getMessage(), e);
		} finally {
			try {
				feedbackStream.close();
			} catch (IOException e) {
				Log.e(TAG, e.getMessage(), e);
			}
		}
		return builder.toString();
	}
}
